openssl: move to 0.9.8t This drops our patches to add blacklist support. I will re-add them shortly. BUG=chromium-os:24755 TEST=build Change-Id: I70d3205f319bd5bb5816a7722cef1f0a993e3c2b Signed-off-by: Elly Jones <ellyjones@chromium.org>
diff --git a/CHANGES b/CHANGES index a0442b5..575bd77 100644 --- a/CHANGES +++ b/CHANGES
@@ -2,9 +2,84 @@ OpenSSL CHANGES _______________ + Changes between 0.9.8s and 0.9.8t [18 Jan 2012] + + *) Fix for DTLS DoS issue introduced by fix for CVE-2011-4109. + Thanks to Antonio Martin, Enterprise Secure Access Research and + Development, Cisco Systems, Inc. for discovering this bug and + preparing a fix. (CVE-2012-0050) + [Antonio Martin] + + Changes between 0.9.8r and 0.9.8s [4 Jan 2012] + + *) Nadhem Alfardan and Kenny Paterson have discovered an extension + of the Vaudenay padding oracle attack on CBC mode encryption + which enables an efficient plaintext recovery attack against + the OpenSSL implementation of DTLS. Their attack exploits timing + differences arising during decryption processing. A research + paper describing this attack can be found at: + http://www.isg.rhul.ac.uk/~kp/dtls.pdf + Thanks go to Nadhem Alfardan and Kenny Paterson of the Information + Security Group at Royal Holloway, University of London + (www.isg.rhul.ac.uk) for discovering this flaw and to Robin Seggelmann + <seggelmann@fh-muenster.de> and Michael Tuexen <tuexen@fh-muenster.de> + for preparing the fix. (CVE-2011-4108) + [Robin Seggelmann, Michael Tuexen] + + *) Stop policy check failure freeing same buffer twice. (CVE-2011-4109) + [Ben Laurie, Kasper <ekasper@google.com>] + + *) Clear bytes used for block padding of SSL 3.0 records. + (CVE-2011-4576) + [Adam Langley (Google)] + + *) Only allow one SGC handshake restart for SSL/TLS. Thanks to George + Kadianakis <desnacked@gmail.com> for discovering this issue and + Adam Langley for preparing the fix. (CVE-2011-4619) + [Adam Langley (Google)] + + *) Prevent malformed RFC3779 data triggering an assertion failure. + Thanks to Andrew Chi, BBN Technologies, for discovering the flaw + and Rob Austein <sra@hactrn.net> for fixing it. (CVE-2011-4577) + [Rob Austein <sra@hactrn.net>] + + *) Fix ssl_ciph.c set-up race. + [Adam Langley (Google)] + + *) Fix spurious failures in ecdsatest.c. + [Emilia Käsper (Google)] + + *) Fix the BIO_f_buffer() implementation (which was mixing different + interpretations of the '..._len' fields). + [Adam Langley (Google)] + + *) Fix handling of BN_BLINDING: now BN_BLINDING_invert_ex (rather than + BN_BLINDING_invert_ex) calls BN_BLINDING_update, ensuring that concurrent + threads won't reuse the same blinding coefficients. + + This also avoids the need to obtain the CRYPTO_LOCK_RSA_BLINDING + lock to call BN_BLINDING_invert_ex, and avoids one use of + BN_BLINDING_update for each BN_BLINDING structure (previously, + the last update always remained unused). + [Emilia Käsper (Google)] + + *) Fix SSL memory handling for (EC)DH ciphersuites, in particular + for multi-threaded use of ECDH. + [Adam Langley (Google)] + + *) Fix x509_name_ex_d2i memory leak on bad inputs. + [Bodo Moeller] + + *) Add protection against ECDSA timing attacks as mentioned in the paper + by Billy Bob Brumley and Nicola Tuveri, see: + + http://eprint.iacr.org/2011/232.pdf + + [Billy Bob Brumley and Nicola Tuveri] + Changes between 0.9.8q and 0.9.8r [8 Feb 2011] - *) Fix parsing of OCSP stapling ClientHello extension. CVE-2011-0014 + *) Fix parsing of OCSP stapling ClientHello extension. CVE-2011-0014 [Neel Mehta, Adam Langley, Bodo Moeller (Google)] *) Fix bug in string printing code: if *any* escaping is enabled we must
diff --git a/FAQ b/FAQ index 0e008cb..2a271ed 100644 --- a/FAQ +++ b/FAQ
@@ -82,7 +82,7 @@ * Which is the current version of OpenSSL? The current version is available from <URL: http://www.openssl.org>. -OpenSSL 1.0.0d was released on Feb 8th, 2011. +OpenSSL 1.0.0g was released on Jan 18th, 2012. In addition to the current stable release, you can also access daily snapshots of the OpenSSL development version at <URL:
diff --git a/Makefile b/Makefile index 1b4cdc1..d435bbe 100644 --- a/Makefile +++ b/Makefile
@@ -4,7 +4,7 @@ ## Makefile for OpenSSL ## -VERSION=0.9.8r +VERSION=0.9.8t MAJOR=0 MINOR=9.8 SHLIB_VERSION_NUMBER=0.9.8
diff --git a/NEWS b/NEWS index 2f9afe8..f33f700 100644 --- a/NEWS +++ b/NEWS
@@ -5,6 +5,18 @@ This file gives a brief overview of the major changes between each OpenSSL release. For more details please read the CHANGES file. + Major changes between OpenSSL 0.9.8s and OpenSSL 0.9.8t: + + o Fix for DTLS DoS issue CVE-2012-0050 + + Major changes between OpenSSL 0.9.8r and OpenSSL 0.9.8s: + + o Fix for DTLS plaintext recovery attack CVE-2011-4108 + o Fix policy check double free error CVE-2011-4109 + o Clear block padding bytes of SSL 3.0 records CVE-2011-4576 + o Only allow one SGC handshake restart for SSL/TLS CVE-2011-4619 + o Check for malformed RFC3779 data CVE-2011-4577 + Major changes between OpenSSL 0.9.8q and OpenSSL 0.9.8r: o Fix for security issue CVE-2011-0014
diff --git a/PRESUBMIT.cfg b/PRESUBMIT.cfg deleted file mode 100644 index 51d8dd6..0000000 --- a/PRESUBMIT.cfg +++ /dev/null
@@ -1,9 +0,0 @@ -# This sample config file disables all of the ChromiumOS source style checks. -# Comment out the disable-flags for any checks you want to leave enabled. - -[Hook Overrides] -stray_whitespace_check: false -long_line_check: false -cros_license_check: false -tab_check: false -
diff --git a/README b/README index 3438b40..9f3f5fd 100644 --- a/README +++ b/README
@@ -1,5 +1,5 @@ - OpenSSL 0.9.8r + OpenSSL 0.9.8t 18 Jan 2012 Copyright (c) 1998-2011 The OpenSSL Project Copyright (c) 1995-1998 Eric A. Young, Tim J. Hudson
diff --git a/apps/asn1pars.c b/apps/asn1pars.c index bde61d0..305cdfc 100644 --- a/apps/asn1pars.c +++ b/apps/asn1pars.c
@@ -408,6 +408,7 @@ atyp = ASN1_generate_nconf(genstr, cnf); NCONF_free(cnf); + cnf = NULL; if (!atyp) return -1;
diff --git a/apps/cms.c b/apps/cms.c index 6d227ac..7407ae1 100644 --- a/apps/cms.c +++ b/apps/cms.c
@@ -611,7 +611,7 @@ BIO_printf (bio_err, "-certsout file certificate output file\n"); BIO_printf (bio_err, "-signer file signer certificate file\n"); BIO_printf (bio_err, "-recip file recipient certificate file for decryption\n"); - BIO_printf (bio_err, "-skeyid use subject key identifier\n"); + BIO_printf (bio_err, "-keyid use subject key identifier\n"); BIO_printf (bio_err, "-in file input file\n"); BIO_printf (bio_err, "-inform arg input format SMIME (default), PEM or DER\n"); BIO_printf (bio_err, "-inkey file input private key (if not signer or recipient)\n");
diff --git a/apps/openssl-vms.cnf b/apps/openssl-vms.cnf index fae82b0..4f60124 100644 --- a/apps/openssl-vms.cnf +++ b/apps/openssl-vms.cnf
@@ -141,7 +141,7 @@ organizationalUnitName = Organizational Unit Name (eg, section) #organizationalUnitName_default = -commonName = Common Name (eg, YOUR name) +commonName = Common Name (e.g. server FQDN or YOUR name) commonName_max = 64 emailAddress = Email Address
diff --git a/apps/openssl.cnf b/apps/openssl.cnf index 9e59020..8fdacae 100644 --- a/apps/openssl.cnf +++ b/apps/openssl.cnf
@@ -141,7 +141,7 @@ organizationalUnitName = Organizational Unit Name (eg, section) #organizationalUnitName_default = -commonName = Common Name (eg, YOUR name) +commonName = Common Name (e.g. server FQDN or YOUR name) commonName_max = 64 emailAddress = Email Address
diff --git a/apps/pkcs12.c b/apps/pkcs12.c index 0db0b79..4860560 100644 --- a/apps/pkcs12.c +++ b/apps/pkcs12.c
@@ -659,7 +659,7 @@ if (!twopass) BUF_strlcpy(macpass, pass, sizeof macpass); - if (options & INFO) BIO_printf (bio_err, "MAC Iteration %ld\n", p12->mac->iter ? ASN1_INTEGER_get (p12->mac->iter) : 1); + if ((options & INFO) && p12->mac) BIO_printf (bio_err, "MAC Iteration %ld\n", p12->mac->iter ? ASN1_INTEGER_get (p12->mac->iter) : 1); if(macver) { #ifdef CRYPTO_MDEBUG CRYPTO_push_info("verify MAC"); diff --git a/apps/x509.c b/apps/x509.c index 151d3a9..b16afd0 100644 --- a/apps/x509.c +++ b/apps/x509.c
@@ -969,7 +969,7 @@ else { pk=load_key(bio_err, - keyfile, FORMAT_PEM, 0, + keyfile, keyformat, 0, passin, e, "request key"); if (pk == NULL) goto end; } diff --git a/config b/config index b9d1c7a..7a958cb 100755 --- a/config +++ b/config
@@ -790,6 +790,10 @@ # options="$options -DATALLA" #fi +($CC -Wa,--help -c -o /dev/null -x assembler /dev/null 2>&1 | \ + grep \\--noexecstack) 2>&1 > /dev/null && \ + options="$options -Wa,--noexecstack" + # gcc < 2.8 does not support -march=ultrasparc if [ "$OUT" = solaris-sparcv9-gcc -a $GCCVER -lt 28 ] then
diff --git a/crypto/asn1/a_object.c b/crypto/asn1/a_object.c index 365e467..3ac2bc2 100644 --- a/crypto/asn1/a_object.c +++ b/crypto/asn1/a_object.c
@@ -139,7 +139,7 @@ ASN1err(ASN1_F_A2D_ASN1_OBJECT,ASN1_R_INVALID_DIGIT); goto err; } - if (!use_bn && l > (ULONG_MAX / 10L)) + if (!use_bn && l >= ((ULONG_MAX - 80) / 10L)) { use_bn = 1; if (!bl) @@ -294,7 +294,7 @@ /* Sanity check OID encoding: can't have leading 0x80 in * subidentifiers, see: X.690 8.19.2 */ - for (i = 0, p = *pp + 1; i < len - 1; i++, p++) + for (i = 0, p = *pp; i < len; i++, p++) { if (*p == 0x80 && (!i || !(p[-1] & 0x80))) { diff --git a/crypto/asn1/x_name.c b/crypto/asn1/x_name.c index 04380ab..9a1a9f4 100644 --- a/crypto/asn1/x_name.c +++ b/crypto/asn1/x_name.c
@@ -196,7 +196,9 @@ *val = nm.a; *in = p; return ret; - err: +err: + if (nm.x != NULL) + X509_NAME_free(nm.x); ASN1err(ASN1_F_X509_NAME_EX_D2I, ERR_R_NESTED_ASN1_ERROR); return 0; }
diff --git a/crypto/bio/bf_buff.c b/crypto/bio/bf_buff.c index c1fd75a..4b5a132 100644 --- a/crypto/bio/bf_buff.c +++ b/crypto/bio/bf_buff.c
@@ -209,7 +209,7 @@ /* add to buffer and return */ if (i >= inl) { - memcpy(&(ctx->obuf[ctx->obuf_len]),in,inl); + memcpy(&(ctx->obuf[ctx->obuf_off+ctx->obuf_len]),in,inl); ctx->obuf_len+=inl; return(num+inl); } @@ -219,7 +219,7 @@ { if (i > 0) /* lets fill it up if we can */ { - memcpy(&(ctx->obuf[ctx->obuf_len]),in,i); + memcpy(&(ctx->obuf[ctx->obuf_off+ctx->obuf_len]),in,i); in+=i; inl-=i; num+=i; @@ -294,9 +294,9 @@ case BIO_C_GET_BUFF_NUM_LINES: ret=0; p1=ctx->ibuf; - for (i=ctx->ibuf_off; i<ctx->ibuf_len; i++) + for (i=0; i<ctx->ibuf_len; i++) { - if (p1[i] == '\n') ret++; + if (p1[ctx->ibuf_off + i] == '\n') ret++; } break; case BIO_CTRL_WPENDING: @@ -399,17 +399,18 @@ for (;;) { BIO_clear_retry_flags(b); - if (ctx->obuf_len > ctx->obuf_off) + if (ctx->obuf_len > 0) { r=BIO_write(b->next_bio, &(ctx->obuf[ctx->obuf_off]), - ctx->obuf_len-ctx->obuf_off); + ctx->obuf_len); #if 0 -fprintf(stderr,"FLUSH [%3d] %3d -> %3d\n",ctx->obuf_off,ctx->obuf_len-ctx->obuf_off,r); +fprintf(stderr,"FLUSH [%3d] %3d -> %3d\n",ctx->obuf_off,ctx->obuf_len,r); #endif BIO_copy_next_retry(b); if (r <= 0) return((long)r); ctx->obuf_off+=r; + ctx->obuf_len-=r; } else { diff --git a/crypto/bio/bio.h b/crypto/bio/bio.h index ebb4278..6b2daa1 100644 --- a/crypto/bio/bio.h +++ b/crypto/bio/bio.h
@@ -321,6 +321,15 @@ typedef struct bio_f_buffer_ctx_struct { + /* Buffers are setup like this: + * + * <---------------------- size -----------------------> + * +---------------------------------------------------+ + * | consumed | remaining | free space | + * +---------------------------------------------------+ + * <-- off --><------- len -------> + */ + /* BIO *bio; */ /* this is now in the BIO struct */ int ibuf_size; /* how big is the input buffer */ int obuf_size; /* how big is the output buffer */ diff --git a/crypto/bio/bss_dgram.c b/crypto/bio/bss_dgram.c index 14ca854..bfbcf9b 100644 --- a/crypto/bio/bss_dgram.c +++ b/crypto/bio/bss_dgram.c
@@ -57,7 +57,6 @@ * */ -#ifndef OPENSSL_NO_DGRAM #include <stdio.h> #include <errno.h> @@ -65,6 +64,7 @@ #include "cryptlib.h" #include <openssl/bio.h> +#ifndef OPENSSL_NO_DGRAM #if defined(OPENSSL_SYS_WIN32) || defined(OPENSSL_SYS_VMS) #include <sys/timeb.h> @@ -288,7 +288,6 @@ */ dgram_adjust_rcv_timeout(b); ret=recvfrom(b->num,out,outl,0,&peer,(void *)&peerlen); - dgram_reset_rcv_timeout(b); if ( ! data->connected && ret >= 0) BIO_ctrl(b, BIO_CTRL_DGRAM_SET_PEER, 0, &peer); @@ -302,6 +301,8 @@ data->_errno = get_last_socket_error(); } } + + dgram_reset_rcv_timeout(b); } return(ret); } @@ -654,9 +655,13 @@ { err=get_last_socket_error(); -#if defined(OPENSSL_SYS_WINDOWS) && 0 /* more microsoft stupidity? perhaps not? Ben 4/1/99 */ - if ((i == -1) && (err == 0)) - return(1); +#if defined(OPENSSL_SYS_WINDOWS) + /* If the socket return value (i) is -1 + * and err is unexpectedly 0 at this point, + * the error code was overwritten by + * another system call before this error + * handling is called. + */ #endif return(BIO_dgram_non_fatal_error(err)); @@ -719,7 +724,6 @@ } return(0); } -#endif static void get_current_time(struct timeval *t) { @@ -737,3 +741,5 @@ gettimeofday(t, NULL); #endif } + +#endif diff --git a/crypto/bn/asm/mo-586.pl b/crypto/bn/asm/mo-586.pl index 0982293..061127e 100644 --- a/crypto/bn/asm/mo-586.pl +++ b/crypto/bn/asm/mo-586.pl
@@ -539,8 +539,10 @@ &jle (&label("sqradd")); &mov ($carry,"edx"); - &lea ("edx",&DWP(0,$sbit,"edx",2)); + &add ("edx","edx"); &shr ($carry,31); + &add ("edx",$sbit); + &adc ($carry,0); &set_label("sqrlast"); &mov ($word,$_n0); &mov ($inp,$_np); diff --git a/crypto/bn/asm/ppc.pl b/crypto/bn/asm/ppc.pl index 806e53a..8444883 100644 --- a/crypto/bn/asm/ppc.pl +++ b/crypto/bn/asm/ppc.pl
@@ -1039,7 +1039,7 @@ addze r11,r0 #mul_add_c(a[3],b[2],c3,c1,c2); $LD r6,`3*$BNSZ`(r4) - $LD r7,`2*$BNSZ`(r4) + $LD r7,`2*$BNSZ`(r5) $UMULL r8,r6,r7 $UMULH r9,r6,r7 addc r12,r8,r12
diff --git a/crypto/bn/bn_blind.c b/crypto/bn/bn_blind.c index c11fb4c..ca7f996 100644 --- a/crypto/bn/bn_blind.c +++ b/crypto/bn/bn_blind.c
@@ -123,7 +123,7 @@ BIGNUM *mod; /* just a reference */ unsigned long thread_id; /* added in OpenSSL 0.9.6j and 0.9.7b; * used only by crypto/rsa/rsa_eay.c, rsa_lib.c */ - unsigned int counter; + int counter; unsigned long flags; BN_MONT_CTX *m_ctx; int (*bn_mod_exp)(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, @@ -157,7 +157,10 @@ if (BN_get_flags(mod, BN_FLG_CONSTTIME) != 0) BN_set_flags(ret->mod, BN_FLG_CONSTTIME); - ret->counter = BN_BLINDING_COUNTER; + /* Set the counter to the special value -1 + * to indicate that this is never-used fresh blinding + * that does not need updating before first use. */ + ret->counter = -1; return(ret); err: if (ret != NULL) BN_BLINDING_free(ret); @@ -186,7 +189,10 @@ goto err; } - if (--(b->counter) == 0 && b->e != NULL && + if (b->counter == -1) + b->counter = 0; + + if (++b->counter == BN_BLINDING_COUNTER && b->e != NULL && !(b->flags & BN_BLINDING_NO_RECREATE)) { /* re-create blinding parameters */ @@ -201,8 +207,8 @@ ret=1; err: - if (b->counter == 0) - b->counter = BN_BLINDING_COUNTER; + if (b->counter == BN_BLINDING_COUNTER) + b->counter = 0; return(ret); } @@ -223,6 +229,12 @@ return(0); } + if (b->counter == -1) + /* Fresh blinding, doesn't need updating. */ + b->counter = 0; + else if (!BN_BLINDING_update(b,ctx)) + return(0); + if (r != NULL) { if (!BN_copy(r, b->Ai)) ret=0; @@ -243,22 +255,19 @@ int ret; bn_check_top(n); - if ((b->A == NULL) || (b->Ai == NULL)) - { - BNerr(BN_F_BN_BLINDING_INVERT_EX,BN_R_NOT_INITIALIZED); - return(0); - } if (r != NULL) ret = BN_mod_mul(n, n, r, b->mod, ctx); else - ret = BN_mod_mul(n, n, b->Ai, b->mod, ctx); - - if (ret >= 0) { - if (!BN_BLINDING_update(b,ctx)) + if (b->Ai == NULL) + { + BNerr(BN_F_BN_BLINDING_INVERT_EX,BN_R_NOT_INITIALIZED); return(0); + } + ret = BN_mod_mul(n, n, b->Ai, b->mod, ctx); } + bn_check_top(n); return(ret); } diff --git a/crypto/bn/bn_gf2m.c b/crypto/bn/bn_gf2m.c index ae642cc..5d90f1e 100644 --- a/crypto/bn/bn_gf2m.c +++ b/crypto/bn/bn_gf2m.c
@@ -607,6 +607,7 @@ { while (!BN_is_odd(u)) { + if (BN_is_zero(u)) goto err; if (!BN_rshift1(u, u)) goto err; if (BN_is_odd(b)) { diff --git a/crypto/conf/conf_api.c b/crypto/conf/conf_api.c index 909d72b..17bae83 100644 --- a/crypto/conf/conf_api.c +++ b/crypto/conf/conf_api.c
@@ -64,6 +64,7 @@ #endif #include <assert.h> +#include <stdlib.h> #include <string.h> #include <openssl/conf.h> #include <openssl/conf_api.h>
diff --git a/crypto/cryptlib.c b/crypto/cryptlib.c index 497d003..dd74ea8 100644 --- a/crypto/cryptlib.c +++ b/crypto/cryptlib.c
@@ -396,7 +396,6 @@ case DLL_THREAD_ATTACH: break; case DLL_THREAD_DETACH: - ERR_remove_state(0); break; case DLL_PROCESS_DETACH: break;
diff --git a/crypto/crypto.h b/crypto/crypto.h index 0e4fb07..fc1374f 100644 --- a/crypto/crypto.h +++ b/crypto/crypto.h
@@ -588,15 +588,15 @@ #endif /* def OPENSSL_FIPS */ +#define OPENSSL_HAVE_INIT 1 +void OPENSSL_init(void); + /* BEGIN ERROR CODES */ /* The following lines are auto generated by the script mkerr.pl. Any changes * made after this point may be overwritten when the script is next run. */ void ERR_load_CRYPTO_strings(void); -#define OPENSSL_HAVE_INIT 1 -void OPENSSL_init(void); - /* Error codes for the CRYPTO functions. */ /* Function codes. */
diff --git a/crypto/ec/ec2_smpl.c b/crypto/ec/ec2_smpl.c index 1aae199..c06b3b6 100644 --- a/crypto/ec/ec2_smpl.c +++ b/crypto/ec/ec2_smpl.c
@@ -821,7 +821,7 @@ field_sqr = group->meth->field_sqr; /* only support affine coordinates */ - if (!point->Z_is_one) goto err; + if (!point->Z_is_one) return -1; if (ctx == NULL) { diff --git a/crypto/ecdsa/ecdsatest.c b/crypto/ecdsa/ecdsatest.c index b07e312..1ad507d 100644 --- a/crypto/ecdsa/ecdsatest.c +++ b/crypto/ecdsa/ecdsatest.c
@@ -168,10 +168,9 @@ return 0; } fbytes_counter ++; - ret = BN_bn2bin(tmp, buf); - if (ret == 0 || ret != num) + if (num != BN_num_bytes(tmp) || !BN_bn2bin(tmp, buf)) ret = 0; - else + else ret = 1; if (tmp) BN_free(tmp); @@ -287,9 +286,13 @@ size_t crv_len = 0, n = 0; EC_KEY *eckey = NULL, *wrong_eckey = NULL; EC_GROUP *group; + ECDSA_SIG *ecdsa_sig = NULL; unsigned char digest[20], wrong_digest[20]; - unsigned char *signature = NULL; - unsigned int sig_len; + unsigned char *signature = NULL; + const unsigned char *sig_ptr; + unsigned char *sig_ptr2; + unsigned char *raw_buf = NULL; + unsigned int sig_len, degree, r_len, s_len, bn_len, buf_len; int nid, ret = 0; /* fill digest values with some random data */ @@ -339,7 +342,8 @@ if (EC_KEY_set_group(eckey, group) == 0) goto builtin_err; EC_GROUP_free(group); - if (EC_GROUP_get_degree(EC_KEY_get0_group(eckey)) < 160) + degree = EC_GROUP_get_degree(EC_KEY_get0_group(eckey)); + if (degree < 160) /* drop the curve */ { EC_KEY_free(eckey); @@ -415,26 +419,89 @@ } BIO_printf(out, "."); (void)BIO_flush(out); - /* modify a single byte of the signature */ - offset = signature[10] % sig_len; - dirt = signature[11]; - signature[offset] ^= dirt ? dirt : 1; + /* wrong length */ + if (ECDSA_verify(0, digest, 20, signature, sig_len - 1, + eckey) == 1) + { + BIO_printf(out, " failed\n"); + goto builtin_err; + } + BIO_printf(out, "."); + (void)BIO_flush(out); + + /* Modify a single byte of the signature: to ensure we don't + * garble the ASN1 structure, we read the raw signature and + * modify a byte in one of the bignums directly. */ + sig_ptr = signature; + if ((ecdsa_sig = d2i_ECDSA_SIG(NULL, &sig_ptr, sig_len)) == NULL) + { + BIO_printf(out, " failed\n"); + goto builtin_err; + } + + /* Store the two BIGNUMs in raw_buf. */ + r_len = BN_num_bytes(ecdsa_sig->r); + s_len = BN_num_bytes(ecdsa_sig->s); + bn_len = (degree + 7) / 8; + if ((r_len > bn_len) || (s_len > bn_len)) + { + BIO_printf(out, " failed\n"); + goto builtin_err; + } + buf_len = 2 * bn_len; + if ((raw_buf = OPENSSL_malloc(buf_len)) == NULL) + goto builtin_err; + /* Pad the bignums with leading zeroes. */ + memset(raw_buf, 0, buf_len); + BN_bn2bin(ecdsa_sig->r, raw_buf + bn_len - r_len); + BN_bn2bin(ecdsa_sig->s, raw_buf + buf_len - s_len); + + /* Modify a single byte in the buffer. */ + offset = raw_buf[10] % buf_len; + dirt = raw_buf[11] ? raw_buf[11] : 1; + raw_buf[offset] ^= dirt; + /* Now read the BIGNUMs back in from raw_buf. */ + if ((BN_bin2bn(raw_buf, bn_len, ecdsa_sig->r) == NULL) || + (BN_bin2bn(raw_buf + bn_len, bn_len, ecdsa_sig->s) == NULL)) + goto builtin_err; + + sig_ptr2 = signature; + sig_len = i2d_ECDSA_SIG(ecdsa_sig, &sig_ptr2); if (ECDSA_verify(0, digest, 20, signature, sig_len, eckey) == 1) { BIO_printf(out, " failed\n"); goto builtin_err; } + /* Sanity check: undo the modification and verify signature. */ + raw_buf[offset] ^= dirt; + if ((BN_bin2bn(raw_buf, bn_len, ecdsa_sig->r) == NULL) || + (BN_bin2bn(raw_buf + bn_len, bn_len, ecdsa_sig->s) == NULL)) + goto builtin_err; + + sig_ptr2 = signature; + sig_len = i2d_ECDSA_SIG(ecdsa_sig, &sig_ptr2); + if (ECDSA_verify(0, digest, 20, signature, sig_len, eckey) != 1) + { + BIO_printf(out, " failed\n"); + goto builtin_err; + } BIO_printf(out, "."); (void)BIO_flush(out); BIO_printf(out, " ok\n"); /* cleanup */ + /* clean bogus errors */ + ERR_clear_error(); OPENSSL_free(signature); signature = NULL; EC_KEY_free(eckey); eckey = NULL; EC_KEY_free(wrong_eckey); wrong_eckey = NULL; + ECDSA_SIG_free(ecdsa_sig); + ecdsa_sig = NULL; + OPENSSL_free(raw_buf); + raw_buf = NULL; } ret = 1; @@ -443,8 +510,12 @@ EC_KEY_free(eckey); if (wrong_eckey) EC_KEY_free(wrong_eckey); + if (ecdsa_sig) + ECDSA_SIG_free(ecdsa_sig); if (signature) OPENSSL_free(signature); + if (raw_buf) + OPENSSL_free(raw_buf); if (curves) OPENSSL_free(curves); diff --git a/crypto/ecdsa/ecs_ossl.c b/crypto/ecdsa/ecs_ossl.c index 551cf50..1bbf328 100644 --- a/crypto/ecdsa/ecs_ossl.c +++ b/crypto/ecdsa/ecs_ossl.c
@@ -144,6 +144,14 @@ } while (BN_is_zero(k)); + /* We do not want timing information to leak the length of k, + * so we compute G*k using an equivalent scalar of fixed + * bit-length. */ + + if (!BN_add(k, k, order)) goto err; + if (BN_num_bits(k) <= BN_num_bits(order)) + if (!BN_add(k, k, order)) goto err; + /* compute r the x-coordinate of generator * k */ if (!EC_POINT_mul(group, tmp_point, k, NULL, NULL, ctx)) { diff --git a/crypto/evp/evp_test.c b/crypto/evp/evp_test.c index 436be20..a36ca7e 100644 --- a/crypto/evp/evp_test.c +++ b/crypto/evp/evp_test.c
@@ -435,6 +435,7 @@ EXIT(3); } } + fclose(f); #ifndef OPENSSL_NO_ENGINE ENGINE_cleanup();
diff --git a/crypto/ocsp/ocsp_lib.c b/crypto/ocsp/ocsp_lib.c index 2745081..441ccb7 100644 --- a/crypto/ocsp/ocsp_lib.c +++ b/crypto/ocsp/ocsp_lib.c
@@ -169,14 +169,14 @@ char *host, *port; - /* dup the buffer since we are going to mess with it */ - buf = BUF_strdup(url); - if (!buf) goto mem_err; - *phost = NULL; *pport = NULL; *ppath = NULL; + /* dup the buffer since we are going to mess with it */ + buf = BUF_strdup(url); + if (!buf) goto mem_err; + /* Check for initial colon */ p = strchr(buf, ':');
diff --git a/crypto/opensslv.h b/crypto/opensslv.h index 385e1f6..8741856 100644 --- a/crypto/opensslv.h +++ b/crypto/opensslv.h
@@ -25,11 +25,11 @@ * (Prior to 0.9.5a beta1, a different scheme was used: MMNNFFRBB for * major minor fix final patch/beta) */ -#define OPENSSL_VERSION_NUMBER 0x0090812fL +#define OPENSSL_VERSION_NUMBER 0x0090814fL #ifdef OPENSSL_FIPS -#define OPENSSL_VERSION_TEXT "OpenSSL 0.9.8r-fips 8 Feb 2011" +#define OPENSSL_VERSION_TEXT "OpenSSL 0.9.8t-fips 18 Jan 2012" #else -#define OPENSSL_VERSION_TEXT "OpenSSL 0.9.8r 8 Feb 2011" +#define OPENSSL_VERSION_TEXT "OpenSSL 0.9.8t 18 Jan 2012" #endif #define OPENSSL_VERSION_PTEXT " part of " OPENSSL_VERSION_TEXT
diff --git a/crypto/perlasm/cbc.pl b/crypto/perlasm/cbc.pl index e43dc9a..6fc2510 100644 --- a/crypto/perlasm/cbc.pl +++ b/crypto/perlasm/cbc.pl
@@ -158,7 +158,6 @@ &jmp_ptr($count); &set_label("ej7"); - &xor("edx", "edx") if $ppro; # ppro friendly &movb(&HB("edx"), &BP(6,$in,"",0)); &shl("edx",8); &set_label("ej6"); @@ -170,7 +169,6 @@ &jmp(&label("ejend")); &set_label("ej3"); &movb(&HB("ecx"), &BP(2,$in,"",0)); - &xor("ecx", "ecx") if $ppro; # ppro friendly &shl("ecx",8); &set_label("ej2"); &movb(&HB("ecx"), &BP(1,$in,"",0)); diff --git a/crypto/rc4/rc4_skey.c b/crypto/rc4/rc4_skey.c index 4478d1a..d1dc912 100644 --- a/crypto/rc4/rc4_skey.c +++ b/crypto/rc4/rc4_skey.c
@@ -138,9 +138,9 @@ */ #ifdef OPENSSL_FIPS unsigned long *ia32cap_ptr = OPENSSL_ia32cap_loc(); - if (ia32cap_ptr && (*ia32cap_ptr & (1<<28))) { + if (ia32cap_ptr && (*ia32cap_ptr & (1<<20))) { #else - if (OPENSSL_ia32cap_P & (1<<28)) { + if (OPENSSL_ia32cap_P & (1<<20)) { #endif unsigned char *cp=(unsigned char *)d; diff --git a/crypto/rsa/rsa_eay.c b/crypto/rsa/rsa_eay.c index 412d0ea..d477f08 100644 --- a/crypto/rsa/rsa_eay.c +++ b/crypto/rsa/rsa_eay.c
@@ -312,51 +312,56 @@ return ret; } -static int rsa_blinding_convert(BN_BLINDING *b, int local, BIGNUM *f, - BIGNUM *r, BN_CTX *ctx) -{ - if (local) +static int rsa_blinding_convert(BN_BLINDING *b, BIGNUM *f, BIGNUM *unblind, + BN_CTX *ctx) + { + if (unblind == NULL) + /* Local blinding: store the unblinding factor + * in BN_BLINDING. */ return BN_BLINDING_convert_ex(f, NULL, b, ctx); else { - int ret; - CRYPTO_r_lock(CRYPTO_LOCK_RSA_BLINDING); - ret = BN_BLINDING_convert_ex(f, r, b, ctx); - CRYPTO_r_unlock(CRYPTO_LOCK_RSA_BLINDING); - return ret; - } -} - -static int rsa_blinding_invert(BN_BLINDING *b, int local, BIGNUM *f, - BIGNUM *r, BN_CTX *ctx) -{ - if (local) - return BN_BLINDING_invert_ex(f, NULL, b, ctx); - else - { + /* Shared blinding: store the unblinding factor + * outside BN_BLINDING. */ int ret; CRYPTO_w_lock(CRYPTO_LOCK_RSA_BLINDING); - ret = BN_BLINDING_invert_ex(f, r, b, ctx); + ret = BN_BLINDING_convert_ex(f, unblind, b, ctx); CRYPTO_w_unlock(CRYPTO_LOCK_RSA_BLINDING); return ret; } -} + } + +static int rsa_blinding_invert(BN_BLINDING *b, BIGNUM *f, BIGNUM *unblind, + BN_CTX *ctx) + { + /* For local blinding, unblind is set to NULL, and BN_BLINDING_invert_ex + * will use the unblinding factor stored in BN_BLINDING. + * If BN_BLINDING is shared between threads, unblind must be non-null: + * BN_BLINDING_invert_ex will then use the local unblinding factor, + * and will only read the modulus from BN_BLINDING. + * In both cases it's safe to access the blinding without a lock. + */ + return BN_BLINDING_invert_ex(f, unblind, b, ctx); + } /* signing */ static int RSA_eay_private_encrypt(int flen, const unsigned char *from, unsigned char *to, RSA *rsa, int padding) { - BIGNUM *f, *ret, *br, *res; + BIGNUM *f, *ret, *res; int i,j,k,num=0,r= -1; unsigned char *buf=NULL; BN_CTX *ctx=NULL; int local_blinding = 0; + /* Used only if the blinding structure is shared. A non-NULL unblind + * instructs rsa_blinding_convert() and rsa_blinding_invert() to store + * the unblinding factor outside the blinding structure. */ + BIGNUM *unblind = NULL; BN_BLINDING *blinding = NULL; if ((ctx=BN_CTX_new()) == NULL) goto err; BN_CTX_start(ctx); f = BN_CTX_get(ctx); - br = BN_CTX_get(ctx); ret = BN_CTX_get(ctx); num = BN_num_bytes(rsa->n); buf = OPENSSL_malloc(num); @@ -404,8 +409,15 @@ } if (blinding != NULL) - if (!rsa_blinding_convert(blinding, local_blinding, f, br, ctx)) + { + if (!local_blinding && ((unblind = BN_CTX_get(ctx)) == NULL)) + { + RSAerr(RSA_F_RSA_EAY_PRIVATE_ENCRYPT,ERR_R_MALLOC_FAILURE); goto err; + } + if (!rsa_blinding_convert(blinding, f, unblind, ctx)) + goto err; + } if ( (rsa->flags & RSA_FLAG_EXT_PKEY) || ((rsa->p != NULL) && @@ -439,7 +451,7 @@ } if (blinding) - if (!rsa_blinding_invert(blinding, local_blinding, ret, br, ctx)) + if (!rsa_blinding_invert(blinding, ret, unblind, ctx)) goto err; if (padding == RSA_X931_PADDING) @@ -478,18 +490,21 @@ static int RSA_eay_private_decrypt(int flen, const unsigned char *from, unsigned char *to, RSA *rsa, int padding) { - BIGNUM *f, *ret, *br; + BIGNUM *f, *ret; int j,num=0,r= -1; unsigned char *p; unsigned char *buf=NULL; BN_CTX *ctx=NULL; int local_blinding = 0; + /* Used only if the blinding structure is shared. A non-NULL unblind + * instructs rsa_blinding_convert() and rsa_blinding_invert() to store + * the unblinding factor outside the blinding structure. */ + BIGNUM *unblind = NULL; BN_BLINDING *blinding = NULL; if((ctx = BN_CTX_new()) == NULL) goto err; BN_CTX_start(ctx); f = BN_CTX_get(ctx); - br = BN_CTX_get(ctx); ret = BN_CTX_get(ctx); num = BN_num_bytes(rsa->n); buf = OPENSSL_malloc(num); @@ -527,8 +542,15 @@ } if (blinding != NULL) - if (!rsa_blinding_convert(blinding, local_blinding, f, br, ctx)) + { + if (!local_blinding && ((unblind = BN_CTX_get(ctx)) == NULL)) + { + RSAerr(RSA_F_RSA_EAY_PRIVATE_DECRYPT,ERR_R_MALLOC_FAILURE); goto err; + } + if (!rsa_blinding_convert(blinding, f, unblind, ctx)) + goto err; + } /* do the decrypt */ if ( (rsa->flags & RSA_FLAG_EXT_PKEY) || @@ -562,7 +584,7 @@ } if (blinding) - if (!rsa_blinding_invert(blinding, local_blinding, ret, br, ctx)) + if (!rsa_blinding_invert(blinding, ret, unblind, ctx)) goto err; p=buf; diff --git a/crypto/x509/x509_vfy.c b/crypto/x509/x509_vfy.c index e1ee95b..b927584 100644 --- a/crypto/x509/x509_vfy.c +++ b/crypto/x509/x509_vfy.c
@@ -94,109 +94,6 @@ } #endif -/* A version of fgets() that returns the first sz - 1 characters of the next - * line from 'in'. The rest of the line is discarded. */ -static int gets_trunc(BIO *in, char *buf, int sz) -{ - char b; - int i = 0; - - while (BIO_read(in, &b, 1)) { - if (i < sz - 1) - buf[i++] = b; - if (!b || b == '\n') - break; - } - - buf[i] = '\0'; - - return i; -} - -/* Converts a byte string into a hex string, null-terminated. The 'out' buffer - * must be at least 2 * insize + 1 bytes long. */ -static void hexify(unsigned char *in, char *out, int insize) -{ - int i; - static const char hex[] = "0123456789abcdef"; - for (i = 0; i < insize; i++) { - out[i * 2] = hex[in[i] >> 4]; - out[i * 2 + 1] = hex[in[i] & 0xf]; - } - out[i * 2] = '\0'; -} - -static int is_blacklisted(X509 *x) -{ - /* See http://tools.ietf.org/html/rfc5280#section-4.1.2.2: - * "Certificate users MUST be able to handle serialNumber values up to - * 20 octets. Conforming CAs MUST NOT use serialNumber values longer - * than 20 octets." - */ - static const int MAX_SERIAL = 20; - static const int MAX_BLACKLIST_LINE = 1024; - - unsigned char md[EVP_MAX_MD_SIZE]; - char hexmd[EVP_MAX_MD_SIZE * 2 + 1]; - char hexserial[MAX_SERIAL * 2 + 1]; - const EVP_MD *hash = EVP_sha256(); - unsigned int n; - char line[MAX_BLACKLIST_LINE]; - BIO *file = BIO_new_file(OPENSSLDIR "/blacklist", "r"); - int ret = 0; - ASN1_INTEGER *serial = NULL; - unsigned int serial_len; - - if (!file) - return 0; - - if (!X509_digest(x, hash, md, &n)) - goto out; - hexify(md, hexmd, n); - serial = X509_get_serialNumber(x); - serial_len = serial->length; - if (serial_len > sizeof(hexserial) / 2) - /* We only match the first MAX_SERIAL bytes of the serial. */ - serial_len = sizeof(hexserial) / 2; - hexify(serial->data, hexserial, serial_len); - - while (gets_trunc(file, line, sizeof(line))) { - char *str = line; - char *cmd = strsep(&str, " "); - char *arg = strsep(&str, " "); - if (!cmd || !arg || cmd[0] == '#') - continue; - if (strchr(arg, '\n')) - *strchr(arg, '\n') = '\0'; - if (!strcmp(cmd, "sha256") && !strcmp(arg, hexmd)) { - ret = 1; - goto out; - } - if (!strcmp(cmd, "serial") && !strcmp(arg, hexserial)) { - ret = 1; - goto out; - } - } - -out: - BIO_free(file); - return ret; -} - -static int check_blacklist(X509_STORE_CTX *ctx) -{ - int i; - X509 *x; - - for (i = 0; i < ctx->last_untrusted; i++) - { - x = sk_X509_value(ctx->chain, i); - if (is_blacklisted(x)) - return 0; - } - return 1; -} - int X509_verify_cert(X509_STORE_CTX *ctx) { X509 *x,*xtmp,*chain_ss=NULL; @@ -354,13 +251,6 @@ /* we now have our chain, lets check it... */ - ok = check_blacklist(ctx); - - if (!ok) { - ctx->error = X509_V_ERR_CERT_REJECTED; - goto end; - } - /* Is last certificate looked up self signed? */ if (!ctx->check_issued(ctx,x,x)) { @@ -488,6 +378,7 @@ else return 0; } + /* Check a certificate chains extensions for consistency * with the supplied purpose @@ -1206,7 +1097,7 @@ atm.length=sizeof(buff2); atm.data=(unsigned char *)buff2; - if (X509_time_adj(&atm,-offset*60, cmp_time) == NULL) + if (X509_time_adj(&atm, offset*60, cmp_time) == NULL) return 0; if (ctm->type == V_ASN1_UTCTIME) @@ -1544,11 +1435,6 @@ else ctx->cert_crl = cert_crl; - if (store && store->check_blacklist) - ctx->check_blacklist = store->check_blacklist; - else - ctx->check_blacklist = check_blacklist; - ctx->check_policy = check_policy; diff --git a/crypto/x509/x509_vfy.h b/crypto/x509/x509_vfy.h index 6c822c9..86ae35f 100644 --- a/crypto/x509/x509_vfy.h +++ b/crypto/x509/x509_vfy.h
@@ -198,7 +198,6 @@ int (*get_crl)(X509_STORE_CTX *ctx, X509_CRL **crl, X509 *x); /* retrieve CRL */ int (*check_crl)(X509_STORE_CTX *ctx, X509_CRL *crl); /* Check CRL validity */ int (*cert_crl)(X509_STORE_CTX *ctx, X509_CRL *crl, X509 *x); /* Check certificate against CRL */ - int (*check_blacklist)(X509_STORE_CTX *ctx, X509 *x); /* Check certificate against blacklist */ int (*cleanup)(X509_STORE_CTX *ctx); CRYPTO_EX_DATA ex_data; @@ -246,7 +245,6 @@ int (*get_crl)(X509_STORE_CTX *ctx, X509_CRL **crl, X509 *x); /* retrieve CRL */ int (*check_crl)(X509_STORE_CTX *ctx, X509_CRL *crl); /* Check CRL validity */ int (*cert_crl)(X509_STORE_CTX *ctx, X509_CRL *crl, X509 *x); /* Check certificate against CRL */ - int (*check_blacklist)(X509_STORE_CTX *ctx, X509 *x); /* Check certificate against blacklist */ int (*check_policy)(X509_STORE_CTX *ctx); int (*cleanup)(X509_STORE_CTX *ctx);
diff --git a/crypto/x509v3/pcy_map.c b/crypto/x509v3/pcy_map.c index f28796e..acd2ede 100644 --- a/crypto/x509v3/pcy_map.c +++ b/crypto/x509v3/pcy_map.c
@@ -70,8 +70,6 @@ static void policy_map_free(X509_POLICY_REF *map) { - if (map->subjectDomainPolicy) - ASN1_OBJECT_free(map->subjectDomainPolicy); OPENSSL_free(map); } @@ -95,6 +93,7 @@ { POLICY_MAPPING *map; X509_POLICY_REF *ref = NULL; + ASN1_OBJECT *subjectDomainPolicyRef; X509_POLICY_DATA *data; X509_POLICY_CACHE *cache = x->policy_cache; int i; @@ -153,13 +152,16 @@ if (!sk_ASN1_OBJECT_push(data->expected_policy_set, map->subjectDomainPolicy)) goto bad_mapping; + /* map->subjectDomainPolicy will be freed when + * cache->data is freed. Set it to NULL to avoid double-free. */ + subjectDomainPolicyRef = map->subjectDomainPolicy; + map->subjectDomainPolicy = NULL; ref = OPENSSL_malloc(sizeof(X509_POLICY_REF)); if (!ref) goto bad_mapping; - ref->subjectDomainPolicy = map->subjectDomainPolicy; - map->subjectDomainPolicy = NULL; + ref->subjectDomainPolicy = subjectDomainPolicyRef; ref->data = data; if (!sk_X509_POLICY_REF_push(cache->maps, ref)) diff --git a/crypto/x509v3/pcy_tree.c b/crypto/x509v3/pcy_tree.c index 89f84bf..92ad0a2 100644 --- a/crypto/x509v3/pcy_tree.c +++ b/crypto/x509v3/pcy_tree.c
@@ -612,6 +612,10 @@ case 2: return 1; + /* Some internal error */ + case -1: + return -1; + /* Some internal error */ case 0: return 0; @@ -691,4 +695,3 @@ return 0; } -
diff --git a/crypto/x509v3/v3_addr.c b/crypto/x509v3/v3_addr.c index d97944f..c0e1d2d 100644 --- a/crypto/x509v3/v3_addr.c +++ b/crypto/x509v3/v3_addr.c
@@ -142,12 +142,13 @@ * Expand the bitstring form of an address into a raw byte array. * At the moment this is coded for simplicity, not speed. */ -static void addr_expand(unsigned char *addr, +static int addr_expand(unsigned char *addr, const ASN1_BIT_STRING *bs, const int length, const unsigned char fill) { - OPENSSL_assert(bs->length >= 0 && bs->length <= length); + if (bs->length < 0 || bs->length > length) + return 0; if (bs->length > 0) { memcpy(addr, bs->data, bs->length); if ((bs->flags & 7) != 0) { @@ -159,6 +160,7 @@ } } memset(addr + bs->length, fill, length - bs->length); + return 1; } /* @@ -181,15 +183,13 @@ return 0; switch (afi) { case IANA_AFI_IPV4: - if (bs->length > 4) + if (!addr_expand(addr, bs, 4, fill)) return 0; - addr_expand(addr, bs, 4, fill); BIO_printf(out, "%d.%d.%d.%d", addr[0], addr[1], addr[2], addr[3]); break; case IANA_AFI_IPV6: - if (bs->length > 16) + if (!addr_expand(addr, bs, 16, fill)) return 0; - addr_expand(addr, bs, 16, fill); for (n = 16; n > 1 && addr[n-1] == 0x00 && addr[n-2] == 0x00; n -= 2) ; for (i = 0; i < n; i += 2) @@ -315,6 +315,12 @@ /* * Sort comparison function for a sequence of IPAddressOrRange * elements. + * + * There's no sane answer we can give if addr_expand() fails, and an + * assertion failure on externally supplied data is seriously uncool, + * so we just arbitrarily declare that if given invalid inputs this + * function returns -1. If this messes up your preferred sort order + * for garbage input, tough noogies. */ static int IPAddressOrRange_cmp(const IPAddressOrRange *a, const IPAddressOrRange *b, @@ -327,22 +333,26 @@ switch (a->type) { case IPAddressOrRange_addressPrefix: - addr_expand(addr_a, a->u.addressPrefix, length, 0x00); + if (!addr_expand(addr_a, a->u.addressPrefix, length, 0x00)) + return -1; prefixlen_a = addr_prefixlen(a->u.addressPrefix); break; case IPAddressOrRange_addressRange: - addr_expand(addr_a, a->u.addressRange->min, length, 0x00); + if (!addr_expand(addr_a, a->u.addressRange->min, length, 0x00)) + return -1; prefixlen_a = length * 8; break; } switch (b->type) { case IPAddressOrRange_addressPrefix: - addr_expand(addr_b, b->u.addressPrefix, length, 0x00); + if (!addr_expand(addr_b, b->u.addressPrefix, length, 0x00)) + return -1; prefixlen_b = addr_prefixlen(b->u.addressPrefix); break; case IPAddressOrRange_addressRange: - addr_expand(addr_b, b->u.addressRange->min, length, 0x00); + if (!addr_expand(addr_b, b->u.addressRange->min, length, 0x00)) + return -1; prefixlen_b = length * 8; break; } @@ -384,6 +394,7 @@ unsigned char mask; int i, j; + OPENSSL_assert(memcmp(min, max, length) <= 0); for (i = 0; i < length && min[i] == max[i]; i++) ; for (j = length - 1; j >= 0 && min[j] == 0x00 && max[j] == 0xFF; j--) @@ -657,22 +668,22 @@ /* * Extract min and max values from an IPAddressOrRange. */ -static void extract_min_max(IPAddressOrRange *aor, +static int extract_min_max(IPAddressOrRange *aor, unsigned char *min, unsigned char *max, int length) { - OPENSSL_assert(aor != NULL && min != NULL && max != NULL); + if (aor == NULL || min == NULL || max == NULL) + return 0; switch (aor->type) { case IPAddressOrRange_addressPrefix: - addr_expand(min, aor->u.addressPrefix, length, 0x00); - addr_expand(max, aor->u.addressPrefix, length, 0xFF); - return; + return (addr_expand(min, aor->u.addressPrefix, length, 0x00) && + addr_expand(max, aor->u.addressPrefix, length, 0xFF)); case IPAddressOrRange_addressRange: - addr_expand(min, aor->u.addressRange->min, length, 0x00); - addr_expand(max, aor->u.addressRange->max, length, 0xFF); - return; + return (addr_expand(min, aor->u.addressRange->min, length, 0x00) && + addr_expand(max, aor->u.addressRange->max, length, 0xFF)); } + return 0; } /* @@ -688,9 +699,10 @@ if (aor == NULL || min == NULL || max == NULL || afi_length == 0 || length < afi_length || (aor->type != IPAddressOrRange_addressPrefix && - aor->type != IPAddressOrRange_addressRange)) + aor->type != IPAddressOrRange_addressRange) || + !extract_min_max(aor, min, max, afi_length)) return 0; - extract_min_max(aor, min, max, afi_length); + return afi_length; } @@ -772,8 +784,9 @@ IPAddressOrRange *a = sk_IPAddressOrRange_value(aors, j); IPAddressOrRange *b = sk_IPAddressOrRange_value(aors, j + 1); - extract_min_max(a, a_min, a_max, length); - extract_min_max(b, b_min, b_max, length); + if (!extract_min_max(a, a_min, a_max, length) || + !extract_min_max(b, b_min, b_max, length)) + return 0; /* * Punt misordered list, overlapping start, or inverted range. @@ -801,14 +814,17 @@ } /* - * Check final range to see if it should be a prefix. + * Check range to see if it's inverted or should be a + * prefix. */ j = sk_IPAddressOrRange_num(aors) - 1; { IPAddressOrRange *a = sk_IPAddressOrRange_value(aors, j); - if (a->type == IPAddressOrRange_addressRange) { - extract_min_max(a, a_min, a_max, length); - if (range_should_be_prefix(a_min, a_max, length) >= 0) + if (a != NULL && a->type == IPAddressOrRange_addressRange) { + if (!extract_min_max(a, a_min, a_max, length)) + return 0; + if (memcmp(a_min, a_max, length) > 0 || + range_should_be_prefix(a_min, a_max, length) >= 0) return 0; } } @@ -842,8 +858,16 @@ unsigned char a_min[ADDR_RAW_BUF_LEN], a_max[ADDR_RAW_BUF_LEN]; unsigned char b_min[ADDR_RAW_BUF_LEN], b_max[ADDR_RAW_BUF_LEN]; - extract_min_max(a, a_min, a_max, length); - extract_min_max(b, b_min, b_max, length); + if (!extract_min_max(a, a_min, a_max, length) || + !extract_min_max(b, b_min, b_max, length)) + return 0; + + /* + * Punt inverted ranges. + */ + if (memcmp(a_min, a_max, length) > 0 || + memcmp(b_min, b_max, length) > 0) + return 0; /* * Punt overlaps. @@ -870,6 +894,20 @@ } } + /* + * Check for inverted final range. + */ + j = sk_IPAddressOrRange_num(aors) - 1; + { + IPAddressOrRange *a = sk_IPAddressOrRange_value(aors, j); + if (a != NULL && a->type == IPAddressOrRange_addressRange) { + unsigned char a_min[ADDR_RAW_BUF_LEN], a_max[ADDR_RAW_BUF_LEN]; + extract_min_max(a, a_min, a_max, length); + if (memcmp(a_min, a_max, length) > 0) + return 0; + } + } + return 1; } @@ -1018,6 +1056,11 @@ X509V3_conf_err(val); goto err; } + if (memcmp(min, max, length_from_afi(afi)) > 0) { + X509V3err(X509V3_F_V2I_IPADDRBLOCKS, X509V3_R_EXTENSION_VALUE_ERROR); + X509V3_conf_err(val); + goto err; + } if (!v3_addr_add_range(addr, afi, safi, min, max)) { X509V3err(X509V3_F_V2I_IPADDRBLOCKS, ERR_R_MALLOC_FAILURE); goto err; @@ -1103,13 +1146,15 @@ p = 0; for (c = 0; c < sk_IPAddressOrRange_num(child); c++) { - extract_min_max(sk_IPAddressOrRange_value(child, c), - c_min, c_max, length); + if (!extract_min_max(sk_IPAddressOrRange_value(child, c), + c_min, c_max, length)) + return -1; for (;; p++) { if (p >= sk_IPAddressOrRange_num(parent)) return 0; - extract_min_max(sk_IPAddressOrRange_value(parent, p), - p_min, p_max, length); + if (!extract_min_max(sk_IPAddressOrRange_value(parent, p), + p_min, p_max, length)) + return 0; if (memcmp(p_max, c_max, length) < 0) continue; if (memcmp(p_min, c_min, length) > 0) diff --git a/doc/ssl/SSL_clear.pod b/doc/ssl/SSL_clear.pod index 8e077e3..d4df1bf 100644 --- a/doc/ssl/SSL_clear.pod +++ b/doc/ssl/SSL_clear.pod
@@ -39,10 +39,16 @@ SSL_clear() resets the SSL object to allow for another connection. The reset operation however keeps several settings of the last sessions (some of these settings were made automatically during the last -handshake). It only makes sense when opening a new session (or reusing -an old one) with the same peer that shares these settings. -SSL_clear() is not a short form for the sequence -L<SSL_free(3)|SSL_free(3)>; L<SSL_new(3)|SSL_new(3)>; . +handshake). It only makes sense for a new connection with the exact +same peer that shares these settings, and may fail if that peer +changes its settings between connections. Use the sequence +L<SSL_get_session(3)|SSL_get_session(3)>; +L<SSL_new(3)|SSL_new(3)>; +L<SSL_set_session(3)|SSL_set_session(3)>; +L<SSL_free(3)|SSL_free(3)> +instead to avoid such failures +(or simply L<SSL_free(3)|SSL_free(3)>; L<SSL_new(3)|SSL_new(3)> +if session reuse is not desired). =head1 RETURN VALUES
diff --git a/engines/e_capi_err.h b/engines/e_capi_err.h index 4c749ec..efa7001 100644 --- a/engines/e_capi_err.h +++ b/engines/e_capi_err.h
@@ -55,6 +55,10 @@ #ifndef HEADER_CAPI_ERR_H #define HEADER_CAPI_ERR_H +#ifdef __cplusplus +extern "C" { +#endif + /* BEGIN ERROR CODES */ /* The following lines are auto generated by the script mkerr.pl. Any changes * made after this point may be overwritten when the script is next run. diff --git a/openssl.spec b/openssl.spec index 9b68b3e..443b686 100644 --- a/openssl.spec +++ b/openssl.spec
@@ -2,7 +2,7 @@ %define libmaj 0 %define libmin 9 %define librel 8 -%define librev r +%define librev t Release: 1 %define openssldir /var/ssl
diff --git a/ssl/bio_ssl.c b/ssl/bio_ssl.c index 420deb7..f0a031c 100644 --- a/ssl/bio_ssl.c +++ b/ssl/bio_ssl.c
@@ -348,7 +348,11 @@ break; case BIO_C_SET_SSL: if (ssl != NULL) + { ssl_free(b); + if (!ssl_new(b)) + return 0; + } b->shutdown=(int)num; ssl=(SSL *)ptr; ((BIO_SSL *)b->ptr)->ssl=ssl; diff --git a/ssl/d1_both.c b/ssl/d1_both.c index 920fb1f..85f4d83 100644 --- a/ssl/d1_both.c +++ b/ssl/d1_both.c
@@ -153,12 +153,11 @@ #endif static unsigned char bitmask_start_values[] = {0xff, 0xfe, 0xfc, 0xf8, 0xf0, 0xe0, 0xc0, 0x80}; -static unsigned char bitmask_end_values[] = {0x00, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f}; +static unsigned char bitmask_end_values[] = {0xff, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f}; /* XDTLS: figure out the right values */ static unsigned int g_probable_mtu[] = {1500 - 28, 512 - 28, 256 - 28}; -static unsigned int dtls1_min_mtu(void); static unsigned int dtls1_guess_mtu(unsigned int curr_mtu); static void dtls1_fix_message_header(SSL *s, unsigned long frag_off, unsigned long frag_len); @@ -264,11 +263,10 @@ return ret; mtu = s->d1->mtu - (DTLS1_HM_HEADER_LENGTH + DTLS1_RT_HEADER_LENGTH); } - - OPENSSL_assert(mtu > 0); /* should have something reasonable now */ - #endif + OPENSSL_assert(s->d1->mtu >= dtls1_min_mtu()); /* should have something reasonable now */ + if ( s->init_off == 0 && type == SSL3_RT_HANDSHAKE) OPENSSL_assert(s->init_num == (int)s->d1->w_msg_hdr.msg_len + DTLS1_HM_HEADER_LENGTH); @@ -464,20 +462,9 @@ memset(msg_hdr, 0x00, sizeof(struct hm_header_st)); - s->d1->handshake_read_seq++; - /* we just read a handshake message from the other side: - * this means that we don't need to retransmit of the - * buffered messages. - * XDTLS: may be able clear out this - * buffer a little sooner (i.e if an out-of-order - * handshake message/record is received at the record - * layer. - * XDTLS: exception is that the server needs to - * know that change cipher spec and finished messages - * have been received by the client before clearing this - * buffer. this can simply be done by waiting for the - * first data segment, but is there a better way? */ - dtls1_clear_record_buffer(s); + /* Don't change sequence numbers while listening */ + if (!s->d1->listen) + s->d1->handshake_read_seq++; s->init_msg = s->init_buf->data + DTLS1_HM_HEADER_LENGTH; return s->init_num; @@ -806,16 +793,24 @@ *ok = 0; return i; } - OPENSSL_assert(i == DTLS1_HM_HEADER_LENGTH); + /* Handshake fails if message header is incomplete */ + if (i != DTLS1_HM_HEADER_LENGTH) + { + al=SSL_AD_UNEXPECTED_MESSAGE; + SSLerr(SSL_F_DTLS1_GET_MESSAGE_FRAGMENT,SSL_R_UNEXPECTED_MESSAGE); + goto f_err; + } /* parse the message fragment header */ dtls1_get_message_header(wire, &msg_hdr); /* * if this is a future (or stale) message it gets buffered - * (or dropped)--no further processing at this time + * (or dropped)--no further processing at this time + * While listening, we accept seq 1 (ClientHello with cookie) + * although we're still expecting seq 0 (ClientHello) */ - if ( msg_hdr.seq != s->d1->handshake_read_seq) + if (msg_hdr.seq != s->d1->handshake_read_seq && !(s->d1->listen && msg_hdr.seq == 1)) return dtls1_process_out_of_seq_message(s, &msg_hdr, ok); len = msg_hdr.msg_len; @@ -876,7 +871,12 @@ /* XDTLS: an incorrectly formatted fragment should cause the * handshake to fail */ - OPENSSL_assert(i == (int)frag_len); + if (i != (int)frag_len) + { + al=SSL3_AD_ILLEGAL_PARAMETER; + SSLerr(SSL_F_DTLS1_GET_MESSAGE_FRAGMENT,SSL3_AD_ILLEGAL_PARAMETER); + goto f_err; + } *ok = 1; @@ -1326,7 +1326,8 @@ dtls1_set_message_header(SSL *s, unsigned char *p, unsigned char mt, unsigned long len, unsigned long frag_off, unsigned long frag_len) { - if ( frag_off == 0) + /* Don't change sequence numbers while listening */ + if (frag_off == 0 && !s->d1->listen) { s->d1->handshake_write_seq = s->d1->next_handshake_write_seq; s->d1->next_handshake_write_seq++; @@ -1379,7 +1380,7 @@ return p; } -static unsigned int +unsigned int dtls1_min_mtu(void) { return (g_probable_mtu[(sizeof(g_probable_mtu) / diff --git a/ssl/d1_clnt.c b/ssl/d1_clnt.c index 0aa77ee..4001a5a 100644 --- a/ssl/d1_clnt.c +++ b/ssl/d1_clnt.c
@@ -403,7 +403,8 @@ case SSL3_ST_CW_CHANGE_A: case SSL3_ST_CW_CHANGE_B: - dtls1_start_timer(s); + if (!s->hit) + dtls1_start_timer(s); ret=dtls1_send_change_cipher_spec(s, SSL3_ST_CW_CHANGE_A,SSL3_ST_CW_CHANGE_B); if (ret <= 0) goto end; @@ -438,7 +439,8 @@ case SSL3_ST_CW_FINISHED_A: case SSL3_ST_CW_FINISHED_B: - dtls1_start_timer(s); + if (!s->hit) + dtls1_start_timer(s); ret=dtls1_send_finished(s, SSL3_ST_CW_FINISHED_A,SSL3_ST_CW_FINISHED_B, s->method->ssl3_enc->client_finished_label,
diff --git a/ssl/d1_lib.c b/ssl/d1_lib.c index 54e1640..2e57b63 100644 --- a/ssl/d1_lib.c +++ b/ssl/d1_lib.c
@@ -145,26 +145,33 @@ return(1); } -void dtls1_free(SSL *s) +static void dtls1_clear_queues(SSL *s) { pitem *item = NULL; hm_fragment *frag = NULL; - - ssl3_free(s); + DTLS1_RECORD_DATA *rdata; while( (item = pqueue_pop(s->d1->unprocessed_rcds.q)) != NULL) { + rdata = (DTLS1_RECORD_DATA *) item->data; + if (rdata->rbuf.buf) + { + OPENSSL_free(rdata->rbuf.buf); + } OPENSSL_free(item->data); pitem_free(item); } - pqueue_free(s->d1->unprocessed_rcds.q); while( (item = pqueue_pop(s->d1->processed_rcds.q)) != NULL) { + rdata = (DTLS1_RECORD_DATA *) item->data; + if (rdata->rbuf.buf) + { + OPENSSL_free(rdata->rbuf.buf); + } OPENSSL_free(item->data); pitem_free(item); } - pqueue_free(s->d1->processed_rcds.q); while( (item = pqueue_pop(s->d1->buffered_messages)) != NULL) { @@ -173,7 +180,6 @@ OPENSSL_free(frag); pitem_free(item); } - pqueue_free(s->d1->buffered_messages); while ( (item = pqueue_pop(s->d1->sent_messages)) != NULL) { @@ -182,15 +188,26 @@ OPENSSL_free(frag); pitem_free(item); } - pqueue_free(s->d1->sent_messages); while ( (item = pqueue_pop(s->d1->buffered_app_data.q)) != NULL) - { + { frag = (hm_fragment *)item->data; OPENSSL_free(frag->fragment); OPENSSL_free(frag); pitem_free(item); + } } + +void dtls1_free(SSL *s) + { + ssl3_free(s); + + dtls1_clear_queues(s); + + pqueue_free(s->d1->unprocessed_rcds.q); + pqueue_free(s->d1->processed_rcds.q); + pqueue_free(s->d1->buffered_messages); + pqueue_free(s->d1->sent_messages); pqueue_free(s->d1->buffered_app_data.q); pq_64bit_free(&(s->d1->bitmap.map)); @@ -204,6 +221,61 @@ void dtls1_clear(SSL *s) { + pqueue unprocessed_rcds; + pqueue processed_rcds; + pqueue buffered_messages; + pqueue sent_messages; + pqueue buffered_app_data; + unsigned int mtu; + + if (s->d1) + { + unprocessed_rcds = s->d1->unprocessed_rcds.q; + processed_rcds = s->d1->processed_rcds.q; + buffered_messages = s->d1->buffered_messages; + sent_messages = s->d1->sent_messages; + buffered_app_data = s->d1->buffered_app_data.q; + mtu = s->d1->mtu; + + dtls1_clear_queues(s); + + pq_64bit_free(&(s->d1->bitmap.map)); + pq_64bit_free(&(s->d1->bitmap.max_seq_num)); + + pq_64bit_free(&(s->d1->next_bitmap.map)); + pq_64bit_free(&(s->d1->next_bitmap.max_seq_num)); + + memset(s->d1, 0, sizeof(*(s->d1))); + + if (s->server) + { + s->d1->cookie_len = sizeof(s->d1->cookie); + } + + if (SSL_get_options(s) & SSL_OP_NO_QUERY_MTU) + { + s->d1->mtu = mtu; + } + + s->d1->unprocessed_rcds.q = unprocessed_rcds; + s->d1->processed_rcds.q = processed_rcds; + s->d1->buffered_messages = buffered_messages; + s->d1->sent_messages = sent_messages; + s->d1->buffered_app_data.q = buffered_app_data; + +#if defined(OPENSSL_SYS_VMS) || defined(VMS_TEST) + s->d1->bitmap.length=64; +#else + s->d1->bitmap.length=sizeof(s->d1->bitmap.map) * 8; +#endif + pq_64bit_init(&(s->d1->bitmap.map)); + pq_64bit_init(&(s->d1->bitmap.max_seq_num)); + + s->d1->next_bitmap.length = s->d1->bitmap.length; + pq_64bit_init(&(s->d1->next_bitmap.map)); + pq_64bit_init(&(s->d1->next_bitmap.max_seq_num)); + } + ssl3_clear(s); if (s->options & SSL_OP_CISCO_ANYCONNECT) s->version=DTLS1_BAD_VER; @@ -352,6 +424,8 @@ memset(&(s->d1->next_timeout), 0, sizeof(struct timeval)); s->d1->timeout_duration = 1; BIO_ctrl(SSL_get_rbio(s), BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT, 0, &(s->d1->next_timeout)); + /* Clear retransmission buffer */ + dtls1_clear_record_buffer(s); } int dtls1_handle_timeout(SSL *s) @@ -371,7 +445,7 @@ { /* fail the connection, enough alerts have been sent */ SSLerr(SSL_F_DTLS1_HANDLE_TIMEOUT,SSL_R_READ_TIMEOUT_EXPIRED); - return 0; + return -1; } state->timeout.read_timeouts++; diff --git a/ssl/d1_pkt.c b/ssl/d1_pkt.c index b840a15..b709ebb 100644 --- a/ssl/d1_pkt.c +++ b/ssl/d1_pkt.c
@@ -335,6 +335,8 @@ SSL3_RECORD *rr; unsigned int mac_size; unsigned char md[EVP_MAX_MD_SIZE]; + int decryption_failed_or_bad_record_mac = 0; + unsigned char *mac = NULL; rr= &(s->s3->rrec); @@ -369,13 +371,10 @@ enc_err = s->method->ssl3_enc->enc(s,0); if (enc_err <= 0) { - if (enc_err == 0) - /* SSLerr() and ssl3_send_alert() have been called */ - goto err; - - /* otherwise enc_err == -1 */ - al=SSL_AD_BAD_RECORD_MAC; - goto f_err; + /* To minimize information leaked via timing, we will always + * perform all computations before discarding the message. + */ + decryption_failed_or_bad_record_mac = 1; } #ifdef TLS_DEBUG @@ -401,28 +400,32 @@ SSLerr(SSL_F_DTLS1_PROCESS_RECORD,SSL_R_PRE_MAC_LENGTH_TOO_LONG); goto f_err; #else - goto err; + decryption_failed_or_bad_record_mac = 1; #endif } /* check the MAC for rr->input (it's in mac_size bytes at the tail) */ - if (rr->length < mac_size) + if (rr->length >= mac_size) { -#if 0 /* OK only for stream ciphers */ - al=SSL_AD_DECODE_ERROR; - SSLerr(SSL_F_DTLS1_PROCESS_RECORD,SSL_R_LENGTH_TOO_SHORT); - goto f_err; -#else - goto err; -#endif + rr->length -= mac_size; + mac = &rr->data[rr->length]; } - rr->length-=mac_size; + else + rr->length = 0; s->method->ssl3_enc->mac(s,md,0); - if (memcmp(md,&(rr->data[rr->length]),mac_size) != 0) + if (mac == NULL || memcmp(md, mac, mac_size) != 0) { - goto err; + decryption_failed_or_bad_record_mac = 1; } } + if (decryption_failed_or_bad_record_mac) + { + /* decryption failed, silently discard message */ + rr->length = 0; + s->packet_length = 0; + goto err; + } + /* r->length is now just compressed */ if (s->expand != NULL) { @@ -616,10 +619,12 @@ /* If this record is from the next epoch (either HM or ALERT), * and a handshake is currently in progress, buffer it since it - * cannot be processed at this time. */ + * cannot be processed at this time. However, do not buffer + * anything while listening. + */ if (is_next_epoch) { - if (SSL_in_init(s) || s->in_handshake) + if ((SSL_in_init(s) || s->in_handshake) && !s->d1->listen) { dtls1_buffer_record(s, &(s->d1->unprocessed_rcds), &rr->seq_num); } diff --git a/ssl/d1_srvr.c b/ssl/d1_srvr.c index 5b31366..c3144da 100644 --- a/ssl/d1_srvr.c +++ b/ssl/d1_srvr.c
@@ -148,6 +148,7 @@ void (*cb)(const SSL *ssl,int type,int val)=NULL; int ret= -1; int new_state,state,skip=0; + int listen; RAND_add(&Time,sizeof(Time),0); ERR_clear_error(); @@ -157,11 +158,15 @@ cb=s->info_callback; else if (s->ctx->info_callback != NULL) cb=s->ctx->info_callback; + + listen = s->d1->listen; /* init things to blank */ s->in_handshake++; if (!SSL_in_init(s) || SSL_in_before(s)) SSL_clear(s); + s->d1->listen = listen; + if (s->cert == NULL) { SSLerr(SSL_F_DTLS1_ACCEPT,SSL_R_NO_CERTIFICATE_SET); @@ -271,11 +276,23 @@ s->init_num=0; + /* Reflect ClientHello sequence to remain stateless while listening */ + if (listen) + { + memcpy(s->s3->write_sequence, s->s3->read_sequence, sizeof(s->s3->write_sequence)); + } + /* If we're just listening, stop here */ - if (s->d1->listen && s->state == SSL3_ST_SW_SRVR_HELLO_A) + if (listen && s->state == SSL3_ST_SW_SRVR_HELLO_A) { ret = 2; s->d1->listen = 0; + /* Set expected sequence numbers + * to continue the handshake. + */ + s->d1->handshake_read_seq = 2; + s->d1->handshake_write_seq = 1; + s->d1->next_handshake_write_seq = 1; goto end; } @@ -284,7 +301,6 @@ case DTLS1_ST_SW_HELLO_VERIFY_REQUEST_A: case DTLS1_ST_SW_HELLO_VERIFY_REQUEST_B: - dtls1_start_timer(s); ret = dtls1_send_hello_verify_request(s); if ( ret <= 0) goto end; s->state=SSL3_ST_SW_FLUSH; @@ -713,9 +729,6 @@ /* number of bytes to write */ s->init_num=p-buf; s->init_off=0; - - /* buffer the message to handle re-xmits */ - dtls1_buffer_message(s, 0); } /* s->state = DTLS1_ST_SW_HELLO_VERIFY_REQUEST_B */ diff --git a/ssl/s3_clnt.c b/ssl/s3_clnt.c index a7cb7a1..2c9fb87 100644 --- a/ssl/s3_clnt.c +++ b/ssl/s3_clnt.c
@@ -878,7 +878,7 @@ /* wrong packet length */ al=SSL_AD_DECODE_ERROR; SSLerr(SSL_F_SSL3_GET_SERVER_HELLO,SSL_R_BAD_PACKET_LENGTH); - goto err; + goto f_err; } return(1); @@ -1713,7 +1713,7 @@ if (n < 6) { /* need at least ticket_lifetime_hint + ticket length */ - al = SSL3_AL_FATAL,SSL_AD_DECODE_ERROR; + al = SSL_AD_DECODE_ERROR; SSLerr(SSL_F_SSL3_GET_NEW_SESSION_TICKET,SSL_R_LENGTH_MISMATCH); goto f_err; } @@ -1724,7 +1724,7 @@ /* ticket_lifetime_hint + ticket_length + ticket */ if (ticklen + 6 != n) { - al = SSL3_AL_FATAL,SSL_AD_DECODE_ERROR; + al = SSL_AD_DECODE_ERROR; SSLerr(SSL_F_SSL3_GET_NEW_SESSION_TICKET,SSL_R_LENGTH_MISMATCH); goto f_err; } diff --git a/ssl/s3_enc.c b/ssl/s3_enc.c index 1539a4c..759231d 100644 --- a/ssl/s3_enc.c +++ b/ssl/s3_enc.c
@@ -479,6 +479,9 @@ /* we need to add 'i-1' padding bytes */ l+=i; + /* the last of these zero bytes will be overwritten + * with the padding length. */ + memset(&rec->input[rec->length], 0, i); rec->length+=i; rec->input[l-1]=(i-1); }
diff --git a/ssl/s3_lib.c b/ssl/s3_lib.c index 8fa4ab0..a406218 100644 --- a/ssl/s3_lib.c +++ b/ssl/s3_lib.c
@@ -1722,11 +1722,17 @@ } #ifndef OPENSSL_NO_DH if (s->s3->tmp.dh != NULL) + { DH_free(s->s3->tmp.dh); + s->s3->tmp.dh = NULL; + } #endif #ifndef OPENSSL_NO_ECDH if (s->s3->tmp.ecdh != NULL) + { EC_KEY_free(s->s3->tmp.ecdh); + s->s3->tmp.ecdh = NULL; + } #endif rp = s->s3->rbuf.buf; @@ -2635,4 +2641,3 @@ } return(ret); } - diff --git a/ssl/s3_srvr.c b/ssl/s3_srvr.c index e2d570f..f610212 100644 --- a/ssl/s3_srvr.c +++ b/ssl/s3_srvr.c
@@ -235,6 +235,7 @@ } s->init_num=0; + s->s3->flags &= ~SSL3_FLAGS_SGC_RESTART_DONE; if (s->state != SSL_ST_RENEGOTIATE) { @@ -697,6 +698,14 @@ int ok; long n; + /* We only allow the client to restart the handshake once per + * negotiation. */ + if (s->s3->flags & SSL3_FLAGS_SGC_RESTART_DONE) + { + SSLerr(SSL_F_SSL3_CHECK_CLIENT_HELLO, SSL_R_MULTIPLE_SGC_RESTARTS); + return -1; + } + /* this function is called when we really expect a Certificate message, * so permit appropriate message length */ n=s->method->ssl_get_message(s, @@ -710,9 +719,7 @@ if (s->s3->tmp.message_type == SSL3_MT_CLIENT_HELLO) { /* Throw away what we have done so far in the current handshake, - * which will now be aborted. (A full SSL_clear would be too much.) - * I hope that tmp.dh is the only thing that may need to be cleared - * when a handshake is not completed ... */ + * which will now be aborted. (A full SSL_clear would be too much.) */ #ifndef OPENSSL_NO_DH if (s->s3->tmp.dh != NULL) { @@ -720,6 +727,14 @@ s->s3->tmp.dh = NULL; } #endif +#ifndef OPENSSL_NO_ECDH + if (s->s3->tmp.ecdh != NULL) + { + EC_KEY_free(s->s3->tmp.ecdh); + s->s3->tmp.ecdh = NULL; + } +#endif + s->s3->flags |= SSL3_FLAGS_SGC_RESTART_DONE; return 2; } return 1; @@ -1329,7 +1344,6 @@ if (s->s3->tmp.dh != NULL) { - DH_free(dh); SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE, ERR_R_INTERNAL_ERROR); goto err; } @@ -1390,7 +1404,6 @@ if (s->s3->tmp.ecdh != NULL) { - EC_KEY_free(s->s3->tmp.ecdh); SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE, ERR_R_INTERNAL_ERROR); goto err; } @@ -1401,12 +1414,11 @@ SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,ERR_R_ECDH_LIB); goto err; } - if (!EC_KEY_up_ref(ecdhp)) + if ((ecdh = EC_KEY_dup(ecdhp)) == NULL) { SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,ERR_R_ECDH_LIB); goto err; } - ecdh = ecdhp; s->s3->tmp.ecdh=ecdh; if ((EC_KEY_get0_public_key(ecdh) == NULL) || @@ -1560,6 +1572,7 @@ (unsigned char *)encodedPoint, encodedlen); OPENSSL_free(encodedPoint); + encodedPoint = NULL; p += encodedlen; } #endif @@ -1949,6 +1962,7 @@ if (i <= 0) { SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,ERR_R_DH_LIB); + BN_clear_free(pub); goto err; } @@ -2262,6 +2276,12 @@ /* Get encoded point length */ i = *p; p += 1; + if (n != 1 + i) + { + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, + ERR_R_EC_LIB); + goto err; + } if (EC_POINT_oct2point(group, clnt_ecpoint, p, i, bn_ctx) == 0) { diff --git a/ssl/ssl.h b/ssl/ssl.h index 7d4e46e..590a369 100644 --- a/ssl/ssl.h +++ b/ssl/ssl.h
@@ -1739,6 +1739,7 @@ #define SSL_F_SSL3_CALLBACK_CTRL 233 #define SSL_F_SSL3_CHANGE_CIPHER_STATE 129 #define SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM 130 +#define SSL_F_SSL3_CHECK_CLIENT_HELLO 292 #define SSL_F_SSL3_CLIENT_HELLO 131 #define SSL_F_SSL3_CONNECT 132 #define SSL_F_SSL3_CTRL 213 @@ -1974,6 +1975,7 @@ #define SSL_R_MISSING_TMP_RSA_KEY 172 #define SSL_R_MISSING_TMP_RSA_PKEY 173 #define SSL_R_MISSING_VERIFY_MESSAGE 174 +#define SSL_R_MULTIPLE_SGC_RESTARTS 325 #define SSL_R_NON_SSLV2_INITIAL_PACKET 175 #define SSL_R_NO_CERTIFICATES_RETURNED 176 #define SSL_R_NO_CERTIFICATE_ASSIGNED 177
diff --git a/ssl/ssl3.h b/ssl/ssl3.h index 2f579c2..b9a85ef 100644 --- a/ssl/ssl3.h +++ b/ssl/ssl3.h
@@ -333,6 +333,17 @@ #define SSL3_FLAGS_DELAY_CLIENT_FINISHED 0x0002 #define SSL3_FLAGS_POP_BUFFER 0x0004 #define TLS1_FLAGS_TLS_PADDING_BUG 0x0008 + +/* SSL3_FLAGS_SGC_RESTART_DONE is set when we + * restart a handshake because of MS SGC and so prevents us + * from restarting the handshake in a loop. It's reset on a + * renegotiation, so effectively limits the client to one restart + * per negotiation. This limits the possibility of a DDoS + * attack where the client handshakes in a loop using SGC to + * restart. Servers which permit renegotiation can still be + * effected, but we can't prevent that. + */ +#define SSL3_FLAGS_SGC_RESTART_DONE 0x0040 typedef struct ssl3_state_st { diff --git a/ssl/ssl_ciph.c b/ssl/ssl_ciph.c index a34680e..a54c06f 100644 --- a/ssl/ssl_ciph.c +++ b/ssl/ssl_ciph.c
@@ -303,6 +303,7 @@ sk_SSL_COMP_push(ssl_comp_methods,comp); } } + sk_SSL_COMP_sort(ssl_comp_methods); } MemCheck_on(); }
diff --git a/ssl/ssl_err.c b/ssl/ssl_err.c index 7eb5202..bd52c98 100644 --- a/ssl/ssl_err.c +++ b/ssl/ssl_err.c
@@ -1,6 +1,6 @@ /* ssl/ssl_err.c */ /* ==================================================================== - * Copyright (c) 1999-2008 The OpenSSL Project. All rights reserved. + * Copyright (c) 1999-2011 The OpenSSL Project. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -137,6 +137,7 @@ {ERR_FUNC(SSL_F_SSL3_CALLBACK_CTRL), "SSL3_CALLBACK_CTRL"}, {ERR_FUNC(SSL_F_SSL3_CHANGE_CIPHER_STATE), "SSL3_CHANGE_CIPHER_STATE"}, {ERR_FUNC(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM), "SSL3_CHECK_CERT_AND_ALGORITHM"}, +{ERR_FUNC(SSL_F_SSL3_CHECK_CLIENT_HELLO), "SSL3_CHECK_CLIENT_HELLO"}, {ERR_FUNC(SSL_F_SSL3_CLIENT_HELLO), "SSL3_CLIENT_HELLO"}, {ERR_FUNC(SSL_F_SSL3_CONNECT), "SSL3_CONNECT"}, {ERR_FUNC(SSL_F_SSL3_CTRL), "SSL3_CTRL"}, @@ -375,6 +376,7 @@ {ERR_REASON(SSL_R_MISSING_TMP_RSA_KEY) ,"missing tmp rsa key"}, {ERR_REASON(SSL_R_MISSING_TMP_RSA_PKEY) ,"missing tmp rsa pkey"}, {ERR_REASON(SSL_R_MISSING_VERIFY_MESSAGE),"missing verify message"}, +{ERR_REASON(SSL_R_MULTIPLE_SGC_RESTARTS) ,"multiple sgc restarts"}, {ERR_REASON(SSL_R_NON_SSLV2_INITIAL_PACKET),"non sslv2 initial packet"}, {ERR_REASON(SSL_R_NO_CERTIFICATES_RETURNED),"no certificates returned"}, {ERR_REASON(SSL_R_NO_CERTIFICATE_ASSIGNED),"no certificate assigned"}, diff --git a/ssl/ssl_lib.c b/ssl/ssl_lib.c index b6b8e60..23de315 100644 --- a/ssl/ssl_lib.c +++ b/ssl/ssl_lib.c
@@ -1000,6 +1000,11 @@ s->max_cert_list=larg; return(l); case SSL_CTRL_SET_MTU: +#ifndef OPENSSL_NO_DTLS1 + if (larg < (long)dtls1_min_mtu()) + return 0; +#endif + if (SSL_version(s) == DTLS1_VERSION || SSL_version(s) == DTLS1_BAD_VER) { diff --git a/ssl/ssl_locl.h b/ssl/ssl_locl.h index e305db4..4741e30 100644 --- a/ssl/ssl_locl.h +++ b/ssl/ssl_locl.h
@@ -877,6 +877,7 @@ int dtls1_is_timer_expired(SSL *s); void dtls1_double_timeout(SSL *s); int dtls1_send_newsession_ticket(SSL *s); +unsigned int dtls1_min_mtu(void); /* some client-only functions */
diff --git a/ssl/t1_lib.c b/ssl/t1_lib.c index 92cac13..cc97258 100644 --- a/ssl/t1_lib.c +++ b/ssl/t1_lib.c
@@ -575,6 +575,12 @@ sdata = data; if (dsize > 0) { + if (s->tlsext_ocsp_exts) + { + sk_X509_EXTENSION_pop_free(s->tlsext_ocsp_exts, + X509_EXTENSION_free); + } + s->tlsext_ocsp_exts = d2i_X509_EXTENSIONS(NULL, &sdata, dsize); diff --git a/test/Makefile b/test/Makefile index 8a3cd68..0b3b3e8 100644 --- a/test/Makefile +++ b/test/Makefile
@@ -161,8 +161,7 @@ test_rand test_bn test_ec test_ecdsa test_ecdh \ test_enc test_x509 test_rsa test_crl test_sid \ test_gen test_req test_pkcs7 test_verify test_dh test_dsa \ - test_ss test_ca test_engine test_evp test_ssl test_ige test_jpake \ - test_blacklist + test_ss test_ca test_engine test_evp test_ssl test_ige test_jpake test_evp: ../util/shlib_wrap.sh ./$(EVPTEST) evptests.txt @@ -246,9 +245,6 @@ @sh ./treq 2>/dev/null @sh ./treq testreq2.pem 2>/dev/null -test_blacklist: - @sh ./tblacklist - test_pkcs7: @sh ./tpkcs7 2>/dev/null @sh ./tpkcs7d 2>/dev/null
diff --git a/test/tblacklist b/test/tblacklist deleted file mode 100644 index 42e4451..0000000 --- a/test/tblacklist +++ /dev/null
@@ -1,73 +0,0 @@ -#!/bin/sh -# Test /etc/ssl/blacklist - -td=$(mktemp -d "openssl-test.XXXXXXXX") - -cat >> "$td/thawte.pem" << EOF ------BEGIN CERTIFICATE----- -MIIDIzCCAoygAwIBAgIEMAAAAjANBgkqhkiG9w0BAQUFADBfMQswCQYDVQQGEwJV -UzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xNzA1BgNVBAsTLkNsYXNzIDMgUHVi -bGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDQwNTEzMDAw -MDAwWhcNMTQwNTEyMjM1OTU5WjBMMQswCQYDVQQGEwJaQTElMCMGA1UEChMcVGhh -d3RlIENvbnN1bHRpbmcgKFB0eSkgTHRkLjEWMBQGA1UEAxMNVGhhd3RlIFNHQyBD -QTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA1NNn0I0Vf67NMf59HZGhPwtx -PKzMyGT7Y/wySweUvW+Aui/hBJPAM/wJMyPpC3QrccQDxtLN4i/1CWPN/0ilAL/g -5/OIty0y3pg25gqtAHvEZEo7hHUD8nCSfQ5i9SGraTaEMXWQ+L/HbIgbBpV8yeWo -3nWhLHpo39XKHIdYYBkCAwEAAaOB/jCB+zASBgNVHRMBAf8ECDAGAQH/AgEAMAsG -A1UdDwQEAwIBBjARBglghkgBhvhCAQEEBAMCAQYwKAYDVR0RBCEwH6QdMBsxGTAX -BgNVBAMTEFByaXZhdGVMYWJlbDMtMTUwMQYDVR0fBCowKDAmoCSgIoYgaHR0cDov -L2NybC52ZXJpc2lnbi5jb20vcGNhMy5jcmwwMgYIKwYBBQUHAQEEJjAkMCIGCCsG -AQUFBzABhhZodHRwOi8vb2NzcC50aGF3dGUuY29tMDQGA1UdJQQtMCsGCCsGAQUF -BwMBBggrBgEFBQcDAgYJYIZIAYb4QgQBBgpghkgBhvhFAQgBMA0GCSqGSIb3DQEB -BQUAA4GBAFWsY+reod3SkF+fC852vhNRj5PZBSvIG3dLrWlQoe7e3P3bB+noOZTc -q3J5Lwa/q4FwxKjt6lM07e8eU9kGx1Yr0Vz00YqOtCuxN5BICEIlxT6Ky3/rbwTR -bcV0oveifHtgPHfNDs5IAn8BL7abN+AqKjbc1YXWrOU/VG+WHgWv ------END CERTIFICATE----- -EOF - -cat >> "$td/google.pem" << EOF ------BEGIN CERTIFICATE----- -MIIDITCCAoqgAwIBAgIQL9+89q6RUm0PmqPfQDQ+mjANBgkqhkiG9w0BAQUFADBM -MQswCQYDVQQGEwJaQTElMCMGA1UEChMcVGhhd3RlIENvbnN1bHRpbmcgKFB0eSkg -THRkLjEWMBQGA1UEAxMNVGhhd3RlIFNHQyBDQTAeFw0wOTEyMTgwMDAwMDBaFw0x -MTEyMTgyMzU5NTlaMGgxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlh -MRYwFAYDVQQHFA1Nb3VudGFpbiBWaWV3MRMwEQYDVQQKFApHb29nbGUgSW5jMRcw -FQYDVQQDFA53d3cuZ29vZ2xlLmNvbTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkC -gYEA6PmGD5D6htffvXImttdEAoN4c9kCKO+IRTn7EOh8rqk41XXGOOsKFQebg+jN -gtXj9xVoRaELGYW84u+E593y17iYwqG7tcFR39SDAqc9BkJb4SLD3muFXxzW2k6L -05vuuWciKh0R73mkszeK9P4Y/bz5RiNQl/Os/CRGK1w7t0UCAwEAAaOB5zCB5DAM -BgNVHRMBAf8EAjAAMDYGA1UdHwQvMC0wK6ApoCeGJWh0dHA6Ly9jcmwudGhhd3Rl -LmNvbS9UaGF3dGVTR0NDQS5jcmwwKAYDVR0lBCEwHwYIKwYBBQUHAwEGCCsGAQUF -BwMCBglghkgBhvhCBAEwcgYIKwYBBQUHAQEEZjBkMCIGCCsGAQUFBzABhhZodHRw -Oi8vb2NzcC50aGF3dGUuY29tMD4GCCsGAQUFBzAChjJodHRwOi8vd3d3LnRoYXd0 -ZS5jb20vcmVwb3NpdG9yeS9UaGF3dGVfU0dDX0NBLmNydDANBgkqhkiG9w0BAQUF -AAOBgQCfQ89bxFApsb/isJr/aiEdLRLDLE5a+RLizrmCUi3nHX4adpaQedEkUjh5 -u2ONgJd8IyAPkU0Wueru9G2Jysa9zCRo1kNbzipYvzwY4OA8Ys+WAi0oR1A04Se6 -z5nRUP8pJcA2NhUzUnC+MY+f6H/nEQyNv4SgQhqAibAxWEEHXw== ------END CERTIFICATE----- -EOF - -# These are from 'openssl x509 -in google.pem -text -fingerprint -sha256' -google_sha256='f641c36cfef49bc071359ecf88eed9317b738b5989416ad401720c0a4e2e6352' -google_serial='2fdfbcf6ae91526d0f9aa3df40343e9a' -blacklist=/etc/ssl/blacklist - -die () { - echo "$@" - exit 1 -} - -verify () { - openssl verify -CAfile "$td/thawte.pem" "$td/google.pem" > "$td/$1.out" 2> "$td/$1.err" -} - -# First, ensure that the cert verifies with no changes. -cp "$blacklist" "$td/old-blacklist" -verify good || die "failed to verify good signature" -echo "serial $google_serial" > "$blacklist" -verify serial && die "verified with blacklisted serial" -echo "sha256 $google_sha256" > "$blacklist" -verify sha256 && die "verified with blacklisted sha256" -cp "$td/old-blacklist" "$blacklist" -rm -rf "$td" -exit 0 diff --git a/util/cygwin.sh b/util/cygwin.sh index 89d1dda..d622852 100755 --- a/util/cygwin.sh +++ b/util/cygwin.sh
@@ -7,8 +7,8 @@ # Uncomment when debugging #set -x -CONFIG_OPTIONS="--prefix=/usr shared no-idea no-rc5 no-mdc2" -INSTALL_PREFIX=/tmp/install +CONFIG_OPTIONS="--prefix=/usr shared zlib no-idea no-rc5" +INSTALL_PREFIX=/tmp/install/INSTALL VERSION= SUBVERSION=$1 @@ -66,7 +66,7 @@ ./config ${CONFIG_OPTIONS} - The IDEA, RC5 and MDC2 algorithms are disabled due to patent and/or + The IDEA and RC5 algorithms are disabled due to patent and/or licensing issues. EOF } @@ -124,8 +124,12 @@ chmod u-w usr/lib/engines/*.so # Runtime package -find etc usr/bin usr/lib/engines usr/share/doc usr/ssl/certs \ - usr/ssl/man/man[157] usr/ssl/misc usr/ssl/openssl.cnf usr/ssl/private \ +tar cjf libopenssl${VERSION//[!0-9]/}-${VERSION}-${SUBVERSION}.tar.bz2 \ + usr/bin/cyg*dll +# Base package +find etc usr/bin/openssl.exe usr/bin/c_rehash usr/lib/engines usr/share/doc \ + usr/ssl/certs usr/ssl/man/man[157] usr/ssl/misc usr/ssl/openssl.cnf \ + usr/ssl/private \ -empty -o \! -type d | tar cjfT openssl-${VERSION}-${SUBVERSION}.tar.bz2 - # Development package @@ -135,6 +139,7 @@ ls -l openssl-${VERSION}-${SUBVERSION}.tar.bz2 ls -l openssl-devel-${VERSION}-${SUBVERSION}.tar.bz2 +ls -l libopenssl${VERSION//[!0-9]/}-${VERSION}-${SUBVERSION}.tar.bz2 cleanup diff --git a/util/mkerr.pl b/util/mkerr.pl index 7a13130..5775b86 100644 --- a/util/mkerr.pl +++ b/util/mkerr.pl
@@ -487,7 +487,7 @@ print OUT <<"EOF"; /* $cfile */ /* ==================================================================== - * Copyright (c) 1999-2010 The OpenSSL Project. All rights reserved. + * Copyright (c) 1999-2011 The OpenSSL Project. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -680,7 +680,7 @@ undef %err_reason_strings; } -if($debug && defined(%notrans)) { +if($debug && %notrans) { print STDERR "The following function codes were not translated:\n"; foreach(sort keys %notrans) {